package com.xixilala.bt

import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothSocket
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import java.io.IOException
import java.util.*

fun log(str:String) {
    Log.e("bt_log","--$str--")
}


/***
 * 一方 socket 关闭了，另一方接收就会报 java.io.IOException: bt socket closed, read return: -1
 *
 * 参考
 * https://developer.android.google.cn/guide/topics/connectivity/bluetooth?hl=zh-cn#ConnectAsAClient
 */
class MainActivity : AppCompatActivity() {


    private val MY_UUID = UUID.fromString("1-1-1-1-1")

    private val REQUEST_BT = 10

    private val btAdapter:BluetoothAdapter? = BluetoothAdapter.getDefaultAdapter()

    private val btDeviceList = ArrayList<BluetoothDevice>()

    private val btReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            if (intent?.action == BluetoothDevice.ACTION_FOUND ) {
                val device = intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
                device?.let {
                    btDeviceList.add(it)
                }
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)


        registerReceiver(btReceiver, IntentFilter().apply {
            addAction(BluetoothDevice.ACTION_FOUND)
        })

        findViewById<View>(R.id.btnOpenBt).setOnClickListener{
            if (btAdapter == null) {
                Toast.makeText(applicationContext, "device not support bluetooth", Toast.LENGTH_SHORT).show()
            } else {
                if (this.btAdapter.isEnabled == false) {
                    val intent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
                    startActivityForResult(intent, REQUEST_BT)
                }
            }
        }
        findViewById<View>(R.id.btnQueryBtDeviceList).setOnClickListener{
            btAdapter?.let {btAdapter->
                if (btAdapter.isEnabled) {
                    val bondedDevices = btAdapter.bondedDevices


                    bondedDevices?.forEach { btDevice->
                        log("binded bt name=${btDevice.name} addr=${btDevice.address} btUUID=${btDevice.uuids.toList()}")

                    }
                    btDeviceList.clear()
                    if (bondedDevices.isNotEmpty()) {
                        btDeviceList.addAll(bondedDevices)
                        Toast.makeText(applicationContext, "has bondedDevices", Toast.LENGTH_SHORT).show()
                    } else {
                        btAdapter.startDiscovery()
                    }
                }
            }
        }

        findViewById<View>(R.id.btnConnThatDevice).setOnClickListener{

            for (item in btDeviceList) {
                if ("r9" == item.name) {
                    ConnectThread(item).start()
                }
            }
        }
    }

    override fun onDestroy() {
        unregisterReceiver(btReceiver)
        super.onDestroy()
    }

    private inner class ConnectThread(device: BluetoothDevice) : Thread() {

        private val mmSocket: BluetoothSocket? by lazy(LazyThreadSafetyMode.NONE) {
            device.createRfcommSocketToServiceRecord(MY_UUID)
        }

        override fun run() {
            // Cancel discovery because it otherwise slows down the connection.
            btAdapter?.cancelDiscovery()


            mmSocket?.use { socket ->
                // Connect to the remote device through the socket. This call blocks
                // until it succeeds or throws an exception.
                socket.connect()

                // The connection attempt succeeded. Perform work associated with
                // the connection in a separate thread.


                while (true) {
                    val temp = Math.random()*1000
                    val data = "1a2b3c${temp.toInt()}".toByteArray()
                    socket.outputStream?.write(data)

                    val date = ByteArray(1024)


                    val len = socket.inputStream.read(date)
                    Log.e("bt_log", "服务器说 = " + String(date,0,len))

                    sleep(1000 * 2)
                }
            }

        }



        // Closes the client socket and causes the thread to finish.
        fun cancel() {
            try {
                mmSocket?.close()
            } catch (e: IOException) {
                log( "Could not close the client socket" )
            }
        }
    }

}

